{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from gs_quant.session import GsSession\n",
    "# external users should substitute their client id and secret; please skip this step if using internal jupyterhub\n",
    "GsSession.use(client_id=None, client_secret=None, scopes=('run_analytics',)) "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Forward Volatility Screen Functions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from gs_quant.data import Dataset\n",
    "from gs_quant.timeseries import last_value, forward_vol,  VolReference\n",
    "from gs_quant.markets.securities import AssetIdentifier, SecurityMaster\n",
    "import pandas as pd\n",
    "pd.options.display.float_format = '{:,.2f}'.format \n",
    "import warnings\n",
    "from datetime import date\n",
    "import matplotlib.pyplot as plt\n",
    "warnings.filterwarnings('ignore')\n",
    "\n",
    "def forward_volatility_screen(crosses, tenor, forward_tenor, start_date, end_date, plot=True):\n",
    "    data = {}\n",
    "    #replace with premium dataset for more history\n",
    "    impvol = Dataset('FXIMPLIEDVOL')\n",
    "    for bbid in crosses:\n",
    "        asset = SecurityMaster.get_asset(bbid, AssetIdentifier.BLOOMBERG_ID)\n",
    "        fwd_vol = forward_vol(asset, tenor=tenor, forward_start_date=forward_tenor, strike_reference=VolReference.DELTA_NEUTRAL, relative_strike=0)\n",
    "        change = fwd_vol.diff(5)\n",
    "        implied = impvol.get_data(start_date , end_date, bbid=bbid, tenor=tenor, deltaStrike='DN', location='NYC')[['impliedVolatility']]\n",
    "        data[bbid] = {f'{tenor}{forward_tenor} Fwd Vol': last_value(fwd_vol),\n",
    "                       '1w Change': last_value(change),\n",
    "                       f'{tenor} Implied Vol': last_value(implied['impliedVolatility'])*100,\n",
    "                      'Roll-down': last_value(fwd_vol) - last_value(implied['impliedVolatility'])*100,\n",
    "                      'Strike to Lows': min(implied['impliedVolatility'])*100 - last_value(fwd_vol),\n",
    "                      'Strike to Highs': max(implied['impliedVolatility'])*100 - last_value(fwd_vol),\n",
    "                      'Diff' : (max(implied['impliedVolatility'])*100 - last_value(fwd_vol)) + (min(implied['impliedVolatility'])*100 - last_value(fwd_vol))\n",
    "                      }\n",
    "    df = pd.DataFrame(data)\n",
    "    fva_screen = df.transpose()\n",
    "    fva_screen = fva_screen.sort_values(by=['Roll-down'])\n",
    "    \n",
    "    if plot:\n",
    "        for fx in fva_screen.index:\n",
    "            plt.scatter(fva_screen.loc[fx]['Roll-down'], fva_screen.loc[fx]['Diff'])\n",
    "            plt.legend(fva_screen.index,loc='best', bbox_to_anchor=(0.9, -0.13), ncol=3)\n",
    "        plt.xlabel('Carry (vols)')\n",
    "        plt.ylabel('Upside vs Downside')\n",
    "        plt.title('Carry vs Upside/Downside')\n",
    "        plt.show()\n",
    "    return fva_screen.style.background_gradient(subset=['Roll-down']).format(\"{:.2f}\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Forward Volatility\n",
    "The FX Structuring desk uses this analysis to screen for the most attractive 6m forward 6m vols in FVA format\n",
    "\n",
    "We are pulling [GS FX Implied Volatility](https://marquee.gs.com/s/developer/datasets/FXIMPLIEDVOL) by default. If you are looking for additional history or coverage, please see our premium version [link](https://marquee.gs.com/s/developer/datasets/FXIMPLIEDVOL_PREMIUM)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Carry vs Upside/Downside\n",
    "\n",
    "Note: Upper left corner shows attractive long vol crosses with low rolldown and high\n",
    "upside vs. downside difference. Lower right corner shows attractive short vol crosses\n",
    "with high carry and low upside vs. downside difference.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from gs_quant.datetime import business_day_offset\n",
    "from dateutil.relativedelta import relativedelta\n",
    "\n",
    "g10 = ['USDJPY', 'EURUSD', 'AUDUSD', 'GBPUSD', 'USDCAD', 'USDNOK', 'NZDUSD', 'USDSEK', 'USDCHF']\n",
    "EM = ['USDBRL', 'USDZAR',  'USDMXN', 'USDCLP','USDPLN', 'USDCZK', 'USDHUF', 'USDSGD', 'USDINR','USDKRW','USDSGD', 'USDINR',\n",
    "            'USDTWD', 'USDTRY', 'USDPHD']\n",
    "\n",
    "\n",
    "forward_tenor = '6m'\n",
    "tenor = '6m'\n",
    "\n",
    "end = business_day_offset(date.today(), -1, roll='forward')\n",
    "start = business_day_offset(end - relativedelta(years=2), -1, roll='forward')\n",
    "\n",
    "screen = forward_volatility_screen(g10, tenor, forward_tenor, start, end, plot=True)\n",
    "screen"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
